package com.cod.render.shapes;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

public class Mesh {
	protected float[] normal;
	protected float[] color;
	protected float[] vertex;
	protected int numVertices;
	protected int index = 0;
	protected boolean hasColors;
	protected boolean hasNormals;
	protected FloatBuffer normals;
	protected FloatBuffer colors;
	protected FloatBuffer vertices;
	int mode = GL10.GL_TRIANGLES;

	public Mesh(int vertices) {
		numVertices = vertices;
		normal = new float[vertices * 3];
		color = new float[vertices * 4];
		vertex = new float[vertices * 3];
	}

	public Mesh(int vertices, int mode) {
		this.mode = mode;
		numVertices = vertices;
		normal = new float[vertices * 3];
		color = new float[vertices * 4];
		vertex = new float[vertices * 3];
	}

	public void normal(float x, float y, float z) {
		normal[index * 3] = x;
		normal[index * 3 + 1] = y;
		normal[index * 3 + 2] = z;
		hasNormals = true;
	}
	
	public void insertNormal(float x, float y, float z, int offset) {
		normal[offset * 3] = x;
		normal[offset * 3 + 1] = y;
		normal[offset * 3 + 2] = z;
		hasNormals = true;
	}
	
	public void color(float r, float g, float b, float a) {
		color[index * 4] = r;
		color[index * 4 + 1] = g;
		color[index * 4 + 2] = b;
		color[index * 4 + 3] = a;
		hasColors = true;
	}

	public void vertex(float x, float y, float z) {
		vertex[index * 3] = x;
		vertex[index * 3 + 1] = y;
		vertex[index * 3 + 2] = z;
		index++;
	}

	public void finish() {
		ByteBuffer buffer = ByteBuffer.allocateDirect(numVertices * 12);
		buffer.order(ByteOrder.nativeOrder());
		vertices = buffer.asFloatBuffer();
		for (int i = 0; i < numVertices * 3; i++)
			vertices.put(vertex[i]);
		vertices.rewind();
		if (hasColors) {
			buffer = ByteBuffer.allocateDirect(numVertices * 16);
			buffer.order(ByteOrder.nativeOrder());
			colors = buffer.asFloatBuffer();
			for (int i = 0; i < numVertices * 4; i++)
				colors.put(color[i]);
			colors.rewind();
		}
		if (hasNormals) {
			buffer = ByteBuffer.allocateDirect(numVertices * 12);
			buffer.order(ByteOrder.nativeOrder());
			normals = buffer.asFloatBuffer();
			for (int i = 0; i < numVertices * 3; i++)
				normals.put(normal[i]);
			normals.rewind();
		}
	}

	public void draw(GL10 gl) {
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glVertexPointer(3 , GL10.GL_FLOAT, 0, vertices);
		if (hasColors) {
			gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
			gl.glColorPointer(numVertices * 4 / 3, GL10.GL_FLOAT, 0, colors);
		}
		if (hasNormals) {
			gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
			gl.glNormalPointer(GL10.GL_FLOAT, 0, normals);
		}
		gl.glDrawArrays(mode, 0, numVertices);
	}
}
